Vue项目实战(PC端)
相关资料
(一) 下载和运行项目
- 线上地址: http://nongye.huruqing.cn
- pc端: git@gitee.com:huruqing/nongye-admin-template.git
npm i
安装依赖npm run serve
运行项目
- 服务器端: git@gitee.com:huruqing/nongye-server-template.git
- 进入项目
- npm i 安装依赖
- npm run dev 运行项目
- 数据库
- 全局安装 json-server
npm i json-server@0.8 -g
- 进入/nongye-server-template/db, 执行 npm i
- 启动数据库 进入/nongye-server-template, 执行
npm run json
- 全局安装 json-server
(二) 路由守卫
vue-router的路由守卫和axios拦截器有着类似的作用
- from 当前路由
- to 要前往的目标路由
- next 执行下一步操作
- next() 进入到目标路由(相当于放行)
- next({ path: '/xxx' }) 跳转到/xxx 路由
// 最初的路由
const router = new Router({
mode: "history",
routes: initRoutes,
});
// 路由白名单
const whiteList = ["/login"];
// 路由守卫
router.beforeEach((to, from, next) => {
if (store.state.token) {
//已经登录: 如果路由是登录页,默认跳转到首页
if (to.path == "/login") {
next({
path: "/home/dashboard",
});
} else {
next();
}
} else {
next("/login");
//没有登录,路由是否在白名单中
if (whiteList.includes(to.path)) {
//放行
next();
} else {
//没在白名单,跳到登录页面
next("/login");
}
}
});
(三) 用户权限控制
用户权限控制的思路是:
- 前端一开始的路由只配置了一些基本的路由
- 用户登录之后, 后台会给前端返回一个角色字段(比如type), 表明用户的身份
- 前端就根据用户的身份(角色字段)配置不同的路由(有的公司由后台返回)
- 前端使用router.addRoutes方法动态添加权限路由。
- 在后台管理系统的侧边栏一般根据路由数组动态渲染,这样不同角色能看到的列表就不一样。
实践: 在各个代码的关键节点打上断点, 查看整个流程
(四) 动态渲染侧边栏
- 让侧边栏组件(layout)作为所有需要侧边栏的父路由组件(父路由有什么内容, 子路由就有什么内容)
- 刚开始创建路由的时候, 只创建无需登录就能访问的路由
- 根据设置权限设置多个路由数组(routes)
- 登录成功的时候添加加权限动态添加相应的路由数组, 并把路由数组存入vuex的store(仓库)
- 渲染侧边栏的时候, 把路由数组(routes)从store取出, 使用v-for进行动态渲染
(五) 深拷贝和浅拷贝
- 基本数据类型, 拷贝与被拷贝的变量之间, 任何一方修改了都不会影响另一方
- 引用数据类型的拷贝就很不一样, 拷贝方式的不一样, 相互影响的程度一样
浅拷贝
只拷贝引用, 拷贝和被拷贝对象, 任何一方的改变都会导致另一方的改变
let obj1 = {a:2}
let obj2 = obj1; // 浅拷贝
深拷贝,分两种
- 只拷贝第一层(缺点, 对象里若有引用类型, 无法拷贝, 只能拷贝第一层)
<script>
let obj1 = {
name: 'zs',
age: 100,
list: [1,2,4]
}
// 深拷贝
let obj2 = {};
for( let key in obj1) {
obj2[key] = obj1[key];
}
obj2.name = '老胡';
obj2.list.push(555);
console.log('obj1:',obj1);
console.log('obj2:',obj2);
</script>
<script>
// 方法2
let obj1 = {
name: 'zs',
age: 100,
list: [1,2,4]
}
let obj2 = {...obj1}
</script>
- 完全拷贝
<script>
let obj1 = {
name: 'zs',
age: 100,
list: [1,2,3,4,5]
}
// 1.想对象变成json字符串
let str = JSON.stringify(obj1);
// 2.把json字符串变成对象
let obj2 = JSON.parse(str);
obj2.name = '老胡';
obj2.list.push(666);
console.log('obj1:',obj1);
console.log('obj2:',obj2);
</script>
(六) canvans和echarts
canvans主要用来做数据可视化
- 百度地图用的就是canvas
- 各种图标也是使用canvas进行绘制
- 一个基于 JavaScript 的开源可视化图表库 链接
// 使用canvas绘制一个矩形
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<canvas id="myCanvas" width="300" height="150" style="border: 1px solid #d3d3d3" ></canvas>
<script>
var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(20, 20, 150, 100);
</script>
</body>
</html>
// 使用echarts绘制图表
<template>
<div>
<div id="main" style="width: 300px;height: 400px;"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
mounted() {
this.draw();
},
methods: {
draw() {
// 获取节点
var chartDom = document.getElementById("main");
// 初始化echarts
var myChart = echarts.init(chartDom);
// 图标选项设置
var option = {
// 标题
title: {
text: "本周销量",
x: "center",
},
// 横轴
xAxis: {
type: "category",
// 横轴数据
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
},
// 纵轴
yAxis: {
type: "value",
},
series: [
{
// 纵轴数据
data: [120, 200, 150, 80, 70, 110, 130],
// 类型为柱状
type: "bar",
// 显示背景颜色
showBackground: true,
// 背景颜色
backgroundStyle: {
color: "rgba(180, 180, 180, 0.2)",
},
},
],
};
// 把选项放入echart对象
myChart.setOption(option);
},
},
};
</script>
(七) 导出表格
- 安装插件
vue-json-excel
, vue3使用xlsx - 到时并使用(main.js)
import JsonExcel from 'vue-json-excel'
Vue.component('downloadExcel', JsonExcel)
- demo
<template>
<div>
<download-excel
:data="json_data"
:fields="json_fields"
type="xlsx"
worksheet="My Worksheet"
name="我的表格.xlsx"
>
<el-button type="primary" size="mini">导出数据 </el-button>
</download-excel>
<el-table :data="json_data">
<el-table-column label="编号" prop="id"></el-table-column>
<el-table-column label="姓名" prop="username"></el-table-column>
<el-table-column label="年龄" prop="age"></el-table-column>
<el-table-column label="备注" prop="desc"></el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
// 表头
json_fields: {
编号: "id",
姓名: "username",
年龄: "age",
备注: "desc",
},
// 表格内容
json_data: [
{
id: "234",
username: "aaa",
age: "11",
desc: "xxxx",
},
{
id: "112",
username: "bbb",
age: "12",
desc: "xxxx",
},
],
};
},
};
</script>
(八) 复制文本
- 安装插件
vue-clipboard2
- 导入并使用插件
// main.js
import VueClipboard from 'vue-clipboard2'
Vue.use(VueClipboard);
- demo
<template>
<div>
<p>
<span>{{ msg }}</span
><button v-clipboard:copy="msg" v-clipboard:success="onCopy">复制</button>
</p>
<p>
<span>{{ msg2 }}</span
><button v-clipboard:copy="msg2" v-clipboard:success="onCopy">复制</button>
</p>
</div>
</template>
<script>
export default {
data() {
return {
msg: "哈哈哈哈哈哈哈哈哈哈",
msg2: "嘿嘿嘿嘿嘿嘿",
};
},
methods: {
onCopy() {
alert("复制成功");
},
},
};
</script>
<style>
</style>
(九) 国际化
- 安装插件
vue-i18n
- 导入和配置插件
- this.$i18n.locale 可以修改语言
// 配置语言包, /src/lang目录下新建en.js和zh.js
// en.js
export const lang = {
account: 'account',
password: 'password',
}
// zh.js
export const lang = {
account: '账号',
password: '密码',
}
// main.js
import VueI18n from "vue-i18n/dist/vue-i18n.esm.js";
Vue.use(VueI18n); // 通过插件的形式挂载
const i18n = new VueI18n({
locale: store.state.lang, // 语言标识
// this.$i18n.locale // 通过切换locale的值来实现语言切换
messages: {
"zh": require("./lang/zh"), // 中文语言包
"en": require("./lang/en"), // 英文语言包
},
});
// 使用
<template>
<div>
<p>{{ $t("lang.account") }}: zhangsan</p>
<p>{{ $t("lang.password") }}: 123456</p>
<button @click="handClick">切换语言</button>
</div>
</template>
<script>
export default {
methods: {
handClick() {
if (this.$i18n.locale === "en") {
this.$i18n.locale = "zh";
} else {
this.$i18n.locale = "en";
}
},
},
};
</script>